from pathlib import Path
from collections import ChainMap
from typing import Union, AnyStr
from attrdict import AttrDict
from parser import Parser
from transformer import Transformer


class Liquid:

    def __init__(self, template, parser_cls=None, transformer_cls=None, config: dict = None, context: dict = None):
        # TODO: CONFIG 需要一个固定格式的校验器
        self.config = self.load_config(config) if config else None
        self.raw = self.load_template(template)
        self.context = context if context else {}
        # TODO: 设计一个Parser
        self.parser_cls = parser_cls if parser_cls else Parser
        # TODO: 设计一个Transformer
        self.transformer_cls = transformer_cls if parser_cls else Transformer

    @staticmethod
    def _load_from_dir(dir_path):
        raise NotImplementedError

    @staticmethod
    def _load_from_file(file_path):
        return open(file_path).read()

    @staticmethod
    def load_template(template: Union[AnyStr, Path]):
        # TODO: 1. 支持加载文件
        # TODO: 2. 支持加载文件夹
        # TODO: 3. 支持直接加载字符串

        try:
            template_path = Path(template)
            if template_path.is_dir():
                return Liquid._load_from_dir(template_path)
            if template_path.is_file():
                return Liquid._load_from_file(template_path)
        except OSError:
            pass

        return template

    @staticmethod
    def load_context(context: dict):
        return AttrDict(context)

    @staticmethod
    def load_config(config: dict):
        return AttrDict(config)

    def render(self, context):
        if context:
            self.context = ChainMap(self.context, context)

        parser = self.parser_cls(context=self.context)
        tree = parser.parse(self.raw)
        transformer = self.transformer_cls(context=self.context)
        return transformer.transform(tree)
